#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
#include <chrono>
#include <thread>
#include <sw/redis++/redis++.h>
#include "Log.hpp"
using std::cout;
using std::endl;
using std::string;
using std::unordered_map;
using std::vector;
using namespace sw::redis;

class RedisManager
{
private:
    std::unique_ptr<Redis> _redis; // 使用智能指针管理连接

private:
    RedisManager()
    {
        try
        {
            // 创建连接选项（带超时设置）
            ConnectionOptions opts;
            opts.host = "120.46.25.211";                          // Redis服务器IP
            opts.port = 6379;                                     // Redis端口
            opts.socket_timeout = std::chrono::milliseconds(200); // 200ms超时

            // 创建Redis连接
            _redis = std::make_unique<Redis>(opts);
        }
        catch (const Error &e)
        {
            LOG(ERROR, "Redis connection failed: %s", e.what());
            throw;
        }
    }

    ~RedisManager() = default;
    RedisManager(const RedisManager &) = delete;
    RedisManager &operator=(const RedisManager &) = delete;

public:
    static RedisManager &GetInstance()
    {
        static RedisManager instance;
        return instance;
    }

    bool InsertToken(const string &token, const string &username, int expireSeconds)
    {
        try
        {
            // 使用SETEX命令，设置过期时间
            _redis->setex(token, std::chrono::seconds(expireSeconds), username);
            LOG(INFO, "Insert token OK: %s", token.c_str());
            return true;
        }
        catch (const TimeoutError &e)
        {
            LOG(ERROR, "Redis operation timeout: %s", e.what());
            return false;
        }
        catch (const Error &e)
        {
            LOG(ERROR, "Redis error: %s", e.what());
            return false;
        }
    }

    std::string GetUserByToken(const string &token)
    {
        try
        {
            // 使用GET命令，返回OptionalString
            auto val = _redis->get(token);
            LOG(INFO, "Get user by token OK: %s", val ? val->c_str() : "");
            return val ? *val : ""; // 转换为空字符串如果不存在
        }
        catch (const TimeoutError &e)
        {
            LOG(ERROR, "Redis operation timeout: %s", e.what());
            return "";
        }
        catch (const Error &e)
        {
            LOG(ERROR, "Redis error: %s", e.what());
            return "";
        }
    }

    bool DeleteToken(const string &token)
    {
        try
        {
            // 使用DEL命令，返回删除数量
            return _redis->del(token) > 0;
        }
        catch (const TimeoutError &e)
        {
            LOG(ERROR, "Redis operation timeout: %s", e.what());
            return false;
        }
        catch (const Error &e)
        {
            LOG(ERROR, "Redis error: %s", e.what());
            return false;
        }
    }
};